<template>
	<div id="engine-container" class="engine-frame"></div>
</template>

<script lang="ts" setup>
import {
	onMounted,
	reactive,
	toRefs,
	computed,
	inject,
	nextTick,
	onUpdated,
	getCurrentInstance
} from 'vue';
import VGE from '../Engine';
import StorageHelper from '@CIF/Runtime/Global/storage';
import { RUNTIME_CFG_ENUM } from '@CIF/Runtime/Global/variable';
import { uuid, getSceneTreeFromBaseMap, getSceneDataByEngineType } from '@CIF/Utils/util';
import Notifier from '@CIF/Utils/Notifier';
import _ from 'lodash';
import { usePrimaryStore } from '@/store';
import { pwdDecrypt } from '@/utils/encryption/pwd.ts';

const store = usePrimaryStore();
const renderer: any = inject('renderer');
const DEFAULT_LAYER_PROPS = {
	isSplit: false, // 是否参与分屏
	opacity: 0 // 不透明度
};
const DEFAULT_LAYER_GROUP_ID = '_cif_default_group';
/**
 * 服务图层缓存
 */
const SERVICE_LAYER_CACHE = {};

/**
 * 数据定制化渲染器
 */
const CUSTOM_DATA_RENDERER: any[] = [];

const SERVICE_CUSTOM_DATA_RENDERER_CACHE = {};
let assetsSize = 0;
let fakeLoadingTime = 3000;
let stepCount = 0;
let step = 1;
let rafId = null;

const state = reactive({
	serviceLayerSetUpdateListeners: [],
	engineSwitchListeners: [],
	// activeEngineType: 'SUPERMAP',
	// serviceLayer: [], // 定义被打开的服务以及对应的二三维图层，包含服务名称，图层名称，图层透明度，位置等等信息，是图层控制组件的数据源
	cacheId: '',
	defaultGroup: DEFAULT_LAYER_GROUP_ID
});

const activeEngineType = computed(() => {
	return store.getActiveEngineType;
});

function _fakeLoadingTimerOfNaiveEngineAssets() {
	if (stepCount < assetsSize - 1) {
		Notifier.updateFetchingProgress(step);
		stepCount += step;
	} else {
		cancelAnimationFrame(rafId);
	}
	rafId = requestAnimationFrame(_fakeLoadingTimerOfNaiveEngineAssets);
}

/**
 * 异步获取VGE引擎顶级对象，避免组件初始化时VGE未初始化情况
 * @returns {Promise<Viewer>} VGE Viewer
 */
const getReadyVGEViewer = async () => {
	return new Promise((resolve = () => {}) => {
		const timer = setInterval(() => {
			const _viewer = VGE.Viewer;
			if (activeEngineType.value === 'SUPERMAP') {
				if (!_viewer) {
					return;
				} else {
					if (!_viewer?.viewer?.scene) {
						return;
					}
				}
			} else if (!_viewer) {
				return;
			}
			resolve(_viewer);
			clearInterval(timer);
		}, 50);
	});
};

/**
 * @description 处理数据定制化渲染器
 * @param {Objects} service - 服务信息
 * @param {String} sLayerId - 服务图层id，在addServiceLayer方式调用时通过option参数指定
 */
function _handleCustomRender(service: any, sLayerId: any) {
	let useCustomRender = false;
	for (let i = 0; i < CUSTOM_DATA_RENDERER.length; i++) {
		if (CUSTOM_DATA_RENDERER[i].match(service, sLayerId)) {
			useCustomRender = true;
			// 通过服务id调用渲染器render和wipe方法
			if (SERVICE_CUSTOM_DATA_RENDERER_CACHE[sLayerId]) {
				// 如果有renderer缓存，判断是否已加入过缓存
				let isCached = false;
				for (let j = 0; j < SERVICE_CUSTOM_DATA_RENDERER_CACHE[sLayerId].length; i++) {
					if (
						SERVICE_CUSTOM_DATA_RENDERER_CACHE[sLayerId][j].uuid === CUSTOM_DATA_RENDERER[i].uuid
					) {
						isCached = true;
						break;
					}
				}
				if (isCached === false) {
					SERVICE_CUSTOM_DATA_RENDERER_CACHE[sLayerId].push(CUSTOM_DATA_RENDERER[i]);
				}
			} else {
				// 空数据初始化
				SERVICE_CUSTOM_DATA_RENDERER_CACHE[sLayerId] = [CUSTOM_DATA_RENDERER[i]];
			}
		}
	}
	return useCustomRender;
}

/**
 * @description 触发引擎类型变更监听器回调
 */
function _dispatchEngineSwitchEvent() {
	state.engineSwitchListeners.forEach((listener: CallableFunction) => {
		listener(VGE._sceneTo, VGE._sceneFrom);
	});
}

/**
 * engineFrame内部加载服务使用
 * @param {String} engineType 引擎类型
 * @param {Objects} serviceAssemble 服务配置
 * @param {Boolean} useCustomRender 是否使用定制化渲染
 * @param {Function} callback 加载服务后回调
 */
function _openService(
	engineType: any,
	serviceAssemble: any = {},
	service: any,
	useCustomRender: any = false,
	callback: any
) {
	const ENGINE_TYPE = engineType.toUpperCase();
	nextTick(async () => {
		let sceneData = {
			sceneTo: ENGINE_TYPE,
			container: 'engine-container',
			cameraParams: {},
			homeView: {}
		};
		// _sceneTo意味着场景已经加载，在引擎内做不同操作
		if (VGE._sceneTo === 'SUPERMAP') {
			if (useCustomRender === true) {
				Promise.all(
					SERVICE_CUSTOM_DATA_RENDERER_CACHE[serviceAssemble.sLayerId].map((dataRenderer) => {
						return new Promise((resolve, reject) => {
							dataRenderer.render(
								service,
								(response, ...otherArgs) => {
									resolve([response, otherArgs]);
								},
								(error) => {
									reject(error);
								}
							);
						});
					})
				)
					.then((responseAndOtherArgsArr) => {
						const layers = responseAndOtherArgsArr.map((x) => x[0]);
						const otherArgs = responseAndOtherArgsArr.map((x) => x[1]);
						callback(layers, otherArgs);
					})
					.catch((error) => {
						console.log('自定义数据渲染器渲染失败', error);
					});
				return;
			}
			sceneData.sceneUrl = [serviceAssemble];
			// }
		} else {
			sceneData.sceneUrl = serviceAssemble;
		}
		sceneData.loadOptions = {
			asyncService: true
		};
		await VGE.open(sceneData, { single: false }, callback);
	});
}

/**
 * @description 获取VGE内部Layer图层id
 * @param serviceLayer - 图层
 * @returns {Array<String>} cLayerId
 */
function getVGELayerIdsFromServiceLayer(serviceLayer: any, engineType: any) {
	const ENGINE_TYPE = engineType.toUpperCase();
	const serviceLayerData = _.get(serviceLayer, 'data', {});
	return _.get(serviceLayerData, '_layers').map((x) => {
		if (!ENGINE_TYPE) {
			return activeEngineType.value === 'SUPERMAP' ? _.get(x, 'iid') : _.get(x, 'id');
		} else {
			return ENGINE_TYPE === 'SUPERMAP' ? _.get(x, 'iid') : _.get(x, 'id');
		}
	});
}

/**
 * @description 获取缓存的资源服务图层
 * @param {String} group 图层组id
 * @returns {Array<ServiceLayer>} Service Layers
 */
function getCacheServiceLayer(group: any = DEFAULT_LAYER_GROUP_ID) {
	if (!SERVICE_LAYER_CACHE[state.cacheId][group]) {
		SERVICE_LAYER_CACHE[state.cacheId][group] = {
			serviceLayer: []
		};
	}
	return SERVICE_LAYER_CACHE[state.cacheId][group].serviceLayer;
}

/**
 * @param {Array<ServiceLayer>} serviceLayer 图层数组
 * @param {String} group 图层组id，未指定则为默认图层组id
 */
function setCacheServiceLayer(serviceLayer: any, group: any = DEFAULT_LAYER_GROUP_ID) {
	if (!SERVICE_LAYER_CACHE[state.cacheId][group]) {
		SERVICE_LAYER_CACHE[state.cacheId][group] = {
			serviceLayer: []
		};
	}
	SERVICE_LAYER_CACHE[state.cacheId][group].serviceLayer = serviceLayer;
}

/**
 * @description !重置缓存图层数据，一般仅在场景切换时使用
 * @param {String} group 图层组id，默认为undefined
 */
function resetCacheServiceLayers(group: any = undefined) {
	if (!group) {
		// group未进行指定，默认清除所有缓存图层
		Object.keys(SERVICE_LAYER_CACHE[state.cacheId]).forEach((key) => {
			SERVICE_LAYER_CACHE[state.cacheId][key] = {
				serviceLayer: []
			};
			_dispatchServiceLoadEvent(key);
		});
	} else {
		// 清除指定group的缓存图层
		SERVICE_LAYER_CACHE[state.cacheId][group] = {
			serviceLayer: []
		};
		_dispatchServiceLoadEvent(group);
	}
}

/**
 * @description 触发服务集合变更监听器回调
 */
function _dispatchServiceLoadEvent(group: any = DEFAULT_LAYER_GROUP_ID) {
	state.serviceLayerSetUpdateListeners
		.filter((listener: any) => listener.group === group)
		.forEach((listener: any) => {
			listener(getCacheServiceLayer(group));
		});
}

/**
 * 加载一条服务
 * @param {Objects} serviceInfo 对应服务管理模块里的一条数据
 * @param {Boolean} manage 是否纳入内部图层管理
 * @param {Objects} options - 服务加载选项
 * - id，图层id，若未指定则默认取service的id
 * - group，图层组id，若未指定则默认取DEFAULT_LAYER_GROUP_ID
 * @returns {Promise<ServiceLayer>}
 */
function addServiceLayer(serviceInfo: any, manage: any = true, options: any = {}) {
	return new Promise((resolve = () => {}, reject = () => {}) => {
		const sLayerId = options.id && typeof options.id === 'string' ? options.id : serviceInfo.id; // 指定图层id
		if (!sLayerId) {
			const errorLog = `CIF.R.R.EngineFrame:addServiceLayer 此服务${serviceInfo.serviceName}请提供图层id参数`;
			console.log(errorLog);
			reject(errorLog);
			return;
		}
		const group =
			options.group && typeof options.group === 'string' ? options.group : DEFAULT_LAYER_GROUP_ID; // 指定图层组

		// options.force = true  // 强制加载

		if (manage === true) {
			const oldLayerIdx = getCacheServiceLayer(group).findIndex((x) => x.id === sLayerId);
			if (oldLayerIdx !== -1) {
				if (_.get(window, 'cif.config.logger.enable', false) === true) {
					console.log(
						`CIF.R.R.EngineFrame:addServiceLayer 此服务${serviceInfo.serviceName}已经被加载过了`
					);
				}
				resolve(getCacheServiceLayer(group)[oldLayerIdx]);
				_dispatchServiceLoadEvent(group);
				return;
			}
		}
		let useCustomRender = _handleCustomRender(serviceInfo, sLayerId);
		let serviceAssemble = {};
		const params = _.isString(serviceInfo.params)
			? JSON.parse(serviceInfo.params)
			: serviceInfo.params || {};
		if (VGE._sceneTo === 'SUPERMAP') {
			switch (serviceInfo.serviceType) {
				case '超图-3D':
					serviceAssemble = {
						publishServer: 'SuperMap',
						serverType: 'SuperMap_rest3D',
						url: serviceInfo.serviceUrl,
						dataUrl: '',
						options: params
					};
					break;
				case '超图-3D-数据集': {
					const datasetDataType = serviceInfo.fieldList?.basicInformationList?.find(
						(x) => x.basicName === '数据类型'
					)?.basicValue;
					switch (datasetDataType) {
						case 'IMG':
							serviceAssemble = {
								publishServer: 'SuperMap',
								serverType: 'SuperMap_3DDATASET-IMG',
								url: serviceInfo.serviceUrl,
								dataUrl: '',
								options: {
									name: serviceInfo.serviceName,
									...params
								}
							};
							break;
						case 'TIN':
							serviceAssemble = {
								publishServer: 'SuperMap',
								serverType: 'SuperMap_TIN',
								url: serviceInfo.serviceUrl,
								options: {
									name: serviceInfo.serviceName,
									...params
								}
							};
							break;
						case 'SCP':
						default:
							serviceAssemble = {
								publishServer: 'SuperMap',
								serverType: 'SuperMap_3DDATASET-SCP',
								url: serviceInfo.serviceUrl,
								dataUrl: '',
								options: {
									name: serviceInfo.serviceName,
									...params
								}
							};
							break;
					}
					break;
				}
				case '超图-2D':
					serviceAssemble = {
						publishServer: 'SuperMap',
						serverType: 'SuperMap_rest2D',
						url: serviceInfo.serviceUrl,
						dataUrl: '',
						options: params
					};
					break;
				case '超图-MAPS':
					serviceAssemble = {
						publishServer: 'SuperMap',
						serverType: 'SuperMap_REST-MAPS',
						url: serviceInfo.serviceUrl,
						dataUrl: '',
						options: params
					};
					break;
				case '超图-矢量瓦片':
				case 'MVT':
					serviceAssemble = {
						publishServer: 'SuperMap',
						serverType: 'SuperMap_MVT',
						url: serviceInfo.serviceUrl,
						name: serviceInfo.serviceName,
						layer: serviceInfo.serviceName,
						...params
					};
					break;
				case '超图-数据服务':
					serviceAssemble = {
						publishServer: 'SuperMap',
						serverType: 'SuperMap_Data',
						url: serviceInfo.serviceUrl,
						dataUrl: ''
					};
					// useCustomRender = true
					break;
				case 'OGC_URL':
					{
						serviceAssemble = {
							publishServer: 'Mapbox',
							serverType: 'OGC_URL',
							url: serviceInfo.serviceUrl,
							dataUrl: '',
							...params
						};
					}
					break;
				case 'OGC_WFS':
					{
						serviceAssemble = {
							publishServer: 'GeoServer',
							serverType: 'OGC_WFS',
							url: serviceInfo.serviceUrl,
							dataUrl: '',
							...params
						};
					}
					break;
				case 'OGC_WMS':
					{
						serviceAssemble = {
							publishServer: 'SuperMap',
							serverType: 'OGC_WMS',
							url: serviceInfo.serviceUrl,
							layers: params.layers || '0',
							...params
						};
					}
					break;
				case 'OGC_WMTS':
					{
						serviceAssemble = {
							publishServer: 'SuperMap',
							serverType: 'OGC_WMTS',
							url: serviceInfo.serviceUrl,
							layer: params.layer || 'cif_default_wmts_layer',
							style: params.style || 'default',
							tileMatrixSetID: params.tileMatrixSetID || '0',
							...params
						};
					}
					break;
				case 'SUPERMAP_Google':
				case 'SUPERMAP_OSM':
				case 'SUPERMAP_AMap':
				default:
					serviceAssemble = {
						publishServer: 'SuperMap',
						serverType: serviceInfo.serviceType || 'SuperMap_Custom',
						url: serviceInfo.serviceUrl,
						dataUrl: '',
						...params
					};
					// useCustomRender = true
					break;
			}
			serviceAssemble.sLayerId = sLayerId;
			_openService(
				activeEngineType.value,
				serviceAssemble,
				serviceInfo,
				useCustomRender,
				(allSettledPromises, otherArgs) => {
					if (!useCustomRender && allSettledPromises[0].status == 'rejected') {
						if (_.get(window, 'cif.config.logger.enable', false) === true) {
							console.log(
								`CIF.R.R.EngineFrame:addServiceLayer 此服务${serviceInfo.serviceName}部分数据加载出错：${allSettledPromises[0].reason}`
							);
						}
						reject(allSettledPromises[0].reason);
					} else {
						let layers;
						if (useCustomRender) {
							layers = useCustomRender;
						} else {
							layers = allSettledPromises[0].value;
						}
						const data = {
							...serviceInfo,
							...DEFAULT_LAYER_PROPS,
							_layers: layers,
							_otherArgs: otherArgs,
							useCustomRender: useCustomRender
						};
						const cacheServiceLayer = { id: sLayerId, data };
						resolve(cacheServiceLayer);
						if (manage === true) {
							getCacheServiceLayer(group).push(cacheServiceLayer);
							_dispatchServiceLoadEvent(group);
						}
					}
				}
			);
		} else if (VGE._sceneTo === 'DTS') {
			const arr = serviceInfo.serviceUrl.split('/');
			const id = arr[arr.length - 1];
			VGE.Viewer.viewer.tileLayer.showAllActors(id);
			const data = {
				...serviceInfo,
				...DEFAULT_LAYER_PROPS,
				_layers: [{ id: id }]
			};
			const cacheServiceLayer = { id: sLayerId, data };
			if (manage === true) {
				getCacheServiceLayer(group).push(cacheServiceLayer);
			}
			// console.log("DTS")
			resolve(cacheServiceLayer);
			_dispatchServiceLoadEvent(group);
		} else if (activeEngineType.value === 'MOD' || activeEngineType.value === 'MODELO') {
			console.log('MOD');
		} else if (activeEngineType.value === 'BMAP') {
			console.log('BMAP');
		} else if (activeEngineType.value === 'TMAP') {
			console.log('TMAP');
		} else if (activeEngineType.value === 'AMAP') {
			console.log('AMAP');
		} else if (activeEngineType.value === 'MAPBOX' || activeEngineType.value === 'MAP') {
			console.log('MAPBOX');
		} else if (activeEngineType.value === 'BIMFACE') {
			console.log('BIMFACE');
		} else if (activeEngineType.value === 'BIMBASE') {
			console.log('BIMBASE');
		}
	});
}

/**
 * 卸载一条服务
 * @param {Objects} serviceInfo 对应服务管理模块里的一条数据
 * @param {Boolean} manage 是否纳入内部图层管理
 * @param {Objects} options 服务加载选项
 * - id，图层id，若未指定则默认取service的id
 * - group，图层组id，若未指定则默认取DEFAULT_LAYER_GROUP_ID
 * @returns {Promise<String>} Service Layer Id 服务图层ID
 */
function removeServiceLayer(serviceInfo: any, manage: any = true, options: any = {}) {
	return new Promise((resolve = () => {}, reject = () => {}) => {
		const sLayerId = options.id && typeof options.id === 'string' ? options.id : serviceInfo.id; // 指定图层id,
		const group =
			options.group && typeof options.group === 'string' ? options.group : DEFAULT_LAYER_GROUP_ID; // 指定图层组

		if (manage) {
			const oldLayerIdx = getCacheServiceLayer(group).findIndex((x) => x.id === sLayerId);
			if (oldLayerIdx === -1) {
				if (_.get(window, 'cif.config.logger.enable', false) === true) {
					console.log(
						`CIF.R.R.EngineFrame:removeServiceLayer 此服务${serviceInfo.serviceName}已经被卸载`
					);
				}
				reject();
				return;
			}
		}

		let serviceLayerData;

		if (manage) {
			serviceLayerData = getCacheServiceLayer(group).find((e) => e.id === sLayerId).data;
		} else {
			serviceLayerData = serviceInfo;
		}
		if (SERVICE_CUSTOM_DATA_RENDERER_CACHE[sLayerId]) {
			try {
				serviceLayerData._layers.forEach((layer, idx) => {
					const otherArgs = serviceLayerData._otherArgs[idx];
					SERVICE_CUSTOM_DATA_RENDERER_CACHE[sLayerId][idx].wipe(layer, ...otherArgs);
				});
			} catch (e) {
				if (_.get(window, 'cif.config.logger.enable', false) === true) {
					console.log('CIF.R.R.EngineFrame:removeServiceLayer 数据定制化渲染器擦除图层失败', e);
				}
			} finally {
				resolve(sLayerId);
				if (manage) {
					setCacheServiceLayer(
						getCacheServiceLayer(group).filter((e) => e.id !== sLayerId),
						group
					);
					_dispatchServiceLoadEvent(group);
				}
			}
			return;
		}

		if (VGE._sceneTo === 'SUPERMAP') {
			switch (serviceLayerData.serviceType) {
				case '超图-3D':
					{
						try {
							for (let i = 0; i < serviceLayerData._layers.length; i++) {
								VGE.Viewer.viewer.scene.layers.remove(serviceLayerData._layers[i].name);
							}
						} catch (e) {
							if (_.get(window, 'cif.config.logger.enable', false) === true) {
								console.log('CIF.R.R.EngineFrame:removeServiceLayer 擦除超图-3D图层失败', e);
							}
						}
						resolve(sLayerId);
						if (manage) {
							setCacheServiceLayer(
								getCacheServiceLayer(group).filter((e) => e.id !== sLayerId),
								group
							);
							_dispatchServiceLoadEvent(group);
						}
					}
					break;
				case '超图-3D-数据集': {
					const datasetDataType = serviceLayerData.fieldList?.basicInformationList?.find(
						(x) => x.basicName === '数据类型'
					)?.basicValue;
					switch (datasetDataType) {
						case 'IMG':
							try {
								for (let i = 0; i < serviceLayerData._layers.length; i++) {
									VGE.Viewer.viewer.imageryLayers.remove(serviceLayerData._layers[i]);
								}
							} catch (e) {
								if (_.get(window, 'cif.config.logger.enable', false) === true) {
									console.log(
										'CIF.R.R.EngineFrame:removeServiceLayer 擦除超图-3D-数据集IMG图层失败',
										e
									);
								}
							}
							resolve(sLayerId);
							if (manage) {
								setCacheServiceLayer(
									getCacheServiceLayer(group).filter((e) => e.id !== sLayerId),
									group
								);
								_dispatchServiceLoadEvent(group);
							}
							break;
						case 'TIN':
							try {
								VGE.Viewer.viewer.scene.terrainProvider =
									new window.Cesium.EllipsoidTerrainProvider({});
							} catch (e) {
								if (_.get(window, 'cif.config.logger.enable', false) === true) {
									console.log(
										'CIF.R.R.EngineFrame:removeServiceLayer 擦除超图-3D-数据集TIN图层失败',
										e
									);
								}
							}
							resolve(sLayerId);
							if (manage) {
								setCacheServiceLayer(
									getCacheServiceLayer(group).filter((e) => e.id !== sLayerId),
									group
								);
								_dispatchServiceLoadEvent(group);
							}
							break;
						case 'SCP':
						default:
							try {
								for (let i = 0; i < serviceLayerData._layers.length; i++) {
									VGE.Viewer.viewer.scene.layers.remove(serviceLayerData._layers[i].name);
								}
							} catch (e) {
								if (_.get(window, 'cif.config.logger.enable', false) === true) {
									console.log(
										'CIF.R.R.EngineFrame:removeServiceLayer 擦除超图-3D-数据集SCP图层失败',
										e
									);
								}
							}
							resolve(sLayerId);
							if (manage) {
								setCacheServiceLayer(
									getCacheServiceLayer(group).filter((e) => e.id !== sLayerId),
									group
								);
								_dispatchServiceLoadEvent(group);
							}
							break;
					}
					break;
				}
				case '超图-2D':
					try {
						for (let i = 0; i < serviceLayerData._layers.length; i++) {
							VGE.Viewer.viewer.imageryLayers.remove(serviceLayerData._layers[i]);
						}
					} catch (e) {
						if (_.get(window, 'cif.config.logger.enable', false) === true) {
							console.log('CIF.R.R.EngineFrame:removeServiceLayer 擦除超图-2D图层失败', e);
						}
					}
					resolve(sLayerId);
					if (manage) {
						setCacheServiceLayer(
							getCacheServiceLayer(group).filter((e) => e.id !== sLayerId),
							group
						);
						_dispatchServiceLoadEvent(group);
					}
					break;
				case '超图-矢量瓦片':
					try {
						for (let i = 0; i < serviceLayerData._layers.length; i++) {
							VGE.Viewer.viewer.scene.removeVectorTileMap(serviceLayerData._layers[i].name);
						}
					} catch (e) {
						if (_.get(window, 'cif.config.logger.enable', false) === true) {
							console.log('CIF.R.R.EngineFrame:removeServiceLayer 擦除超图-矢量瓦片图层失败', e);
						}
					}
					resolve(sLayerId);
					if (manage) {
						setCacheServiceLayer(
							getCacheServiceLayer(group).filter((e) => e.id !== sLayerId),
							group
						);
						_dispatchServiceLoadEvent(group);
					}
					break;
				case 'OGC_URL':
				case 'OGC_WMTS':
				case 'OGC_WFS':
					try {
						for (let i = 0; i < serviceLayerData._layers.length; i++) {
							VGE.Viewer.viewer.imageryLayers.remove(serviceLayerData._layers[i]);
						}
					} catch (e) {
						if (_.get(window, 'cif.config.logger.enable', false) === true) {
							console.log('CIF.R.R.EngineFrame:removeServiceLayer 擦除OGC图层失败', e);
						}
					}
					resolve(sLayerId);
					if (manage) {
						setCacheServiceLayer(
							getCacheServiceLayer(group).filter((e) => e.id !== sLayerId),
							group
						);
						_dispatchServiceLoadEvent(group);
					}
					break;
				default:
					break;
			}
		} else if (VGE._sceneTo === 'DTS') {
			console.log('DTS');
			// hideAllActors
			const arr = serviceLayerData.serviceUrl.split('/');
			const id = arr[arr.length - 1];
			VGE.Viewer.viewer.tileLayer.hideAllActors(id);
			resolve(sLayerId);
			if (manage) {
				setCacheServiceLayer(
					getCacheServiceLayer(group).filter((e) => e.id !== sLayerId),
					group
				);
				_dispatchServiceLoadEvent(group);
			}
		} else {
			console.log('else');
		}
	});
}

/**
 * 场景切换使用
 * @param {Objects} sceneData - 必填
 * @param {Objects} options  可选参数
 * - 场景容器container
 * - 镜头参数cameraParams
 * - 主视角参数homeView
 * @param {Function} callback 回调参数
 * @returns {void}
 */
async function openScene(sceneData: any = {}, options: any = {}, callback: any) {
	const ENGINE_TYPE = sceneData.sceneTo.toUpperCase();

	let group = options.group ? options.group : ENGINE_TYPE;

	const openSceneData = Object.assign(sceneData, options);

	if (activeEngineType.value != ENGINE_TYPE) {
		switch (ENGINE_TYPE) {
			case 'MAPBOX':
				fakeLoadingTime = 3000;
				break;
			case 'SUPERMAP':
				fakeLoadingTime = 3000;
				break;
			case 'DTS':
				fakeLoadingTime = 3000;
				break;
			case 'BIMBASE':
				fakeLoadingTime = 3000;
				break;
		}
		assetsSize = (fakeLoadingTime / 1000) * 60;
		stepCount = 0;

		Notifier.resetFetchingProgress();
		Notifier.addsToCountOfRemoteLoadingAssets(assetsSize);
		_fakeLoadingTimerOfNaiveEngineAssets();
	}

	/**
	 * 初始化VGE Scene
	 */
	nextTick(async () => {
		await VGE.open(openSceneData, {}, callback);
		if (activeEngineType.value != ENGINE_TYPE) {
			if (stepCount < assetsSize) {
				Notifier.updateFetchingProgress(assetsSize - stepCount);
			}
			cancelAnimationFrame(rafId);
		}
		store.setActiveEngineType(ENGINE_TYPE);
		_dispatchEngineSwitchEvent();
		resetCacheServiceLayers(group);
	});
}

async function switchEngine(engineType: string) {
	const ctx = StorageHelper.get(RUNTIME_CFG_ENUM.CONTEXT_OPTIONS);
	const sceneTree = StorageHelper.get(RUNTIME_CFG_ENUM.APPLICATION_SCENE_TREE);
	const sceneData = await getSceneDataByEngineType(sceneTree, engineType);
	openScene(sceneData, ctx, undefined);
}

/**
 * @description 注册服务集合变更监听器
 * @param {Function} listener
 * @param {String} group 图层组id，未指定则为默认图层组id
 */
function registryServiceLayerSetUpdateListener(listener: any, group: any = DEFAULT_LAYER_GROUP_ID) {
	listener.group = group;
	state.serviceLayerSetUpdateListeners.push(listener);
}
/**
 * 注册引擎类型变更监听器
 * @param {Function} listener
 */
function registerEngineSwitchListener(listener: any) {
	state.engineSwitchListeners.push(listener);
}
/**
 * @description 注册自定义数据渲染器
 * - match 方法用于匹配服务信息，第一个参数为服务信息，第二个参数为图层id, 返回true表示击中
 * - render 方法用于加载渲染数据, 第一个参数为服务信息，第二个参数为successCallback，第三个参数为errorCallback，successCallback返回的数据将被wipe方法接收，允许返回多个数据，但第一个数据要求是图层数据
 * - wipe 方法用于卸载服务，接收从successCallback返回的一到多个数据
 * @property {{match: Function, render: Function, wipe: Function}} DataRenderer 对象
 * @param {DataRenderer} dataRenderer
 */
function registerCustomDataRenderer(dataRenderer: any) {
	// 自定义数据渲染器需要提供用于匹配服务的 match 方法
	// 用于加载渲染数据的 render 方法，以及用于卸载服务的 wipe 方法
	if (
		dataRenderer.match &&
		typeof dataRenderer.match === 'function' &&
		dataRenderer.render &&
		typeof dataRenderer.render === 'function' &&
		dataRenderer.wipe &&
		typeof dataRenderer.wipe === 'function'
	) {
		dataRenderer.uuid = uuid();
		CUSTOM_DATA_RENDERER.push(dataRenderer);
	}
}
/**
 * 获取引擎顶级对象
 * @returns {VGE} VGE
 */
function getVGE() {
	return VGE;
}

state.cacheId = uuid();
SERVICE_LAYER_CACHE[state.cacheId] = {};
SERVICE_LAYER_CACHE[state.cacheId][DEFAULT_LAYER_GROUP_ID] = {
	serviceLayer: []
};

onMounted(async () => {
	if (_.get(window, 'cif.config.logger.enable', false) === true) {
		console.log('CIF.R.R.EngineFrame:mounted');
	}
	// 响应式给 Renderer 中的 engine 赋值
	renderer.state.engine = getCurrentInstance();
	const ctx = StorageHelper.get(RUNTIME_CFG_ENUM.CONTEXT_OPTIONS);
	const baseMap = StorageHelper.get(RUNTIME_CFG_ENUM.APPLICATION_BASEMAP);
	const engineType = StorageHelper.get(RUNTIME_CFG_ENUM.DEFAULT_ENGINE_TYPE);
	const sceneTree = await getSceneTreeFromBaseMap(baseMap, engineType);
	const sceneData = await getSceneDataByEngineType(sceneTree, engineType);
	StorageHelper.set(RUNTIME_CFG_ENUM.APPLICATION_SCENE_TREE, sceneTree);
	openScene(sceneData, ctx, undefined);
});

onUpdated(() => {
	if (_.get(window, 'cif.config.logger.enable', false) === true) {
		console.log('CIF.R.R.EngineFrame:updated');
	}
});

defineExpose({
	...toRefs(state),
	getReadyVGEViewer,
	getVGELayerIdsFromServiceLayer,
	getCacheServiceLayer,
	setCacheServiceLayer,
	resetCacheServiceLayers,
	addServiceLayer,
	removeServiceLayer,
	openScene,
	switchEngine,
	registryServiceLayerSetUpdateListener,
	registerEngineSwitchListener,
	registerCustomDataRenderer,
	getVGE
});
</script>

<style lang="scss" scoped>
.scene-container {
	width: 100%;
	height: 100%;
}
</style>
